package com.wisdudu.blank.data.source.remote.client.retrofit.subscribers;

import android.content.Context;

import com.orhanobut.logger.Logger;
import com.wisdudu.blank.data.exception.ApiException;
import com.wisdudu.blank.data.source.remote.client.retrofit.subscribers.progress.ProgressCancelListener;
import com.wisdudu.blank.data.source.remote.client.retrofit.subscribers.progress.ProgressDialogHandler;
import com.wisdudu.blank.support.util.ToastUtil;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import rx.Subscriber;

/**
 * 用于在Http请求开始时，自动显示一个ProgressDialog
 * 在Http请求结束是，关闭ProgressDialog
 * 调用者自己对请求数据进行处理
 * Created by liukun on 16/3/10.
 */
public class ProgressSubscriber<T> extends Subscriber<T> implements ProgressCancelListener {

    private SubscriberOnNextListener<T> mSubscriberOnNextListener;
    private ProgressDialogHandler mProgressDialogHandler;
    private long delayDismissTime;

    public Context getContext() {
        return context;
    }

    private Context context;

    /**
     * 构造方法
     *
     * @param cancelable       该ProgressBar是否可取消
     * @param message          ProgressBar开始转动时显示的message
     * @param delayDismissTime 当取消时，如果需要设置文字或图标变动,设置显示时间
     */
    public ProgressSubscriber(SubscriberOnNextListener<T> mSubscriberOnNextListener, Context context, boolean cancelable, String message, long delayDismissTime) {
        this.mSubscriberOnNextListener = mSubscriberOnNextListener;
        this.context = context;
        this.delayDismissTime = delayDismissTime;
        mProgressDialogHandler = new ProgressDialogHandler(context, this, cancelable, message);
    }

    public ProgressSubscriber(SubscriberOnNextListener<T> mSubscriberOnNextListener, Context context, String message, long delayDismissTime) {
        this.mSubscriberOnNextListener = mSubscriberOnNextListener;
        this.context = context;
        this.delayDismissTime = delayDismissTime;
        mProgressDialogHandler = new ProgressDialogHandler(context, this, true, message);
    }

    public ProgressSubscriber(SubscriberOnNextListener<T> mSubscriberOnNextListener, Context context) {
        this(mSubscriberOnNextListener, context, null, 0);
    }

    public ProgressSubscriber(SubscriberOnNextListener<T> mSubscriberOnNextListener, Context context, boolean cancelable) {
        this(mSubscriberOnNextListener, context, cancelable, null, 0);
    }

    public ProgressSubscriber(SubscriberOnNextListener<T> mSubscriberOnNextListener, Context context, String message) {
        this(mSubscriberOnNextListener, context, message, 0);
    }

    public ProgressSubscriber(SubscriberOnNextListener<T> mSubscriberOnNextListener, Context context, boolean cancelable, String message) {
        this(mSubscriberOnNextListener, context, cancelable, message, 0);
    }

    public ProgressSubscriber(SubscriberOnNextListener<T> mSubscriberOnNextListener, Context context, long delayDismissTime) {
        this(mSubscriberOnNextListener, context, null, delayDismissTime);
    }

    public ProgressSubscriber(SubscriberOnNextListener<T> mSubscriberOnNextListener, Context context, boolean cancelable, long delayDismissTime) {
        this(mSubscriberOnNextListener, context, cancelable, null, delayDismissTime);
    }


    private void showProgressDialog() {
        if (mProgressDialogHandler != null) {
            mProgressDialogHandler.obtainMessage(ProgressDialogHandler.SHOW_PROGRESS_DIALOG).sendToTarget();
        }
    }


    private void dismissProgressDialog() {
        if (mProgressDialogHandler != null) {
            mProgressDialogHandler.sendEmptyMessage(ProgressDialogHandler.END_PROGRESS_DIALOG_LOADING);
            mProgressDialogHandler.sendEmptyMessageDelayed(ProgressDialogHandler.DISMISS_PROGRESS_DIALOG, delayDismissTime);
//            mProgressDialogHandler.obtainMessage(ProgressDialogHandler.DISMISS_PROGRESS_DIALOG).sendToTarget();
            mProgressDialogHandler = null;
        }
    }

    /**
     * 订阅开始时调用
     * 显示ProgressDialog
     */
    @Override
    public void onStart() {
        showProgressDialog();
    }

    /**
     * 完成，隐藏ProgressDialog
     */
    @Override
    public void onCompleted() {
        dismissProgressDialog();
    }

    /**
     * 对错误进行统一处理
     * 隐藏ProgressDialog
     *
     * @param e
     */
    @Override
    public void onError(Throwable e) {
        Logger.d("发生异常" + e.toString());
        if (mSubscriberOnNextListener instanceof SubscriberOnNextErrorListener) {
            ((SubscriberOnNextErrorListener) mSubscriberOnNextListener).onError(e, mProgressDialogHandler.pd);
        } else {
            if (e instanceof SocketTimeoutException) {
                ToastUtil.INSTANCE.toast("网络中断，请检查您的网络状态");
            } else if (e instanceof ConnectException) {
                ToastUtil.INSTANCE.toast("网络中断，请检查您的网络状态");
            } else if (e instanceof ApiException) {
                ToastUtil.INSTANCE.toast(e.getMessage());
            } else if (e instanceof UnknownHostException) {
                ToastUtil.INSTANCE.toast("请检查网络连接");
            } else {
                Logger.d("发生异常" + e.toString());
                ToastUtil.INSTANCE.toast("未知异常，需要补全");
            }
        }

        dismissProgressDialog();
    }

    /**
     * 将onNext方法中的返回结果交给Activity或Fragment自己处理
     *
     * @param t 创建Subscriber时的泛型类型
     */
    @Override
    public void onNext(T t) {
        if (mSubscriberOnNextListener != null) {
            mSubscriberOnNextListener.onNext(t, mProgressDialogHandler.pd);
        }
    }

    /**
     * 取消ProgressDialog的时候，取消对observable的订阅，同时也取消了http请求
     */
    @Override
    public void onCancelProgress() {
        if (!this.isUnsubscribed()) {
            this.unsubscribe();
        }
    }
}